package dian.qing.li.demo.security.config.security;

import com.alibaba.fastjson.JSON;
import com.pactera.redis.utils.RedisUtils;
import dian.qing.li.demo.security.commons.RestResult;
import dian.qing.li.demo.security.constants.Constants;
import dian.qing.li.demo.security.constants.RedisKey;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 验证码校验
 *
 * @author: liqingdian
 **/
public class VerifyCodeFilter implements Filter {

    private static final AntPathRequestMatcher LOGIN_MATCHER = new AntPathRequestMatcher("/login", "POST");

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if (LOGIN_MATCHER.matches(request)) {
            // 必须参数校验
            String uniquekey = request.getHeader(Constants.VERIFY_CODE_HEADER);
            boolean next = this.check(StringUtils.isBlank(uniquekey), response, "验证码标识不能为空");
            if (next) return;
            String verifyCode = request.getParameter(Constants.VERIFY_CODE_PARAM);
            next = this.check(StringUtils.isBlank(verifyCode), response, "验证码不能为空");
            if (next) return;
            String redisKey = RedisUtils.redisKey(RedisKey.VERIFY_CODE, uniquekey);
            String redisCode = RedisUtils.get(redisKey, String.class);
            next = this.check(!StringUtils.equalsIgnoreCase(verifyCode.trim(), redisCode), response, "验证码错误");
            if (next) return;
            RedisUtils.delete(redisKey);
        }
        filterChain.doFilter(request, response);
    }

    /**
     * 校验
     *
     * @author: liqingdian
     */
    private boolean check(boolean check, HttpServletResponse response, String msg) throws IOException {
        if (check) {
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setStatus(HttpServletResponse.SC_OK);
            RestResult failed = RestResult.failed(msg);
            PrintWriter out = response.getWriter();
            out.write(JSON.toJSONString(failed, Constants.FASTJSON_SERIALIZER));
            out.flush();
            out.close();
            return true;
        }
        return false;
    }
}
